package com.example.demo.util;


import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
    /**
     * 判断字符串是否为空
     *
     * @param str null、“ ”、“null”都返回true
     * @return
     */
    public static boolean isNullString(String str) {
        return (null == str || StringUtils.isEmpty(str.trim()) || "null".equals(str.trim().toLowerCase())) ? true : false;
    }

    /**
     * 判断字符串Ip地址是否为空
     *
     * @param str null、“ ”、“unknown”都返回true
     * @return
     */
    public static boolean isNullIp(String str) {
        return (null == str || StringUtils.isEmpty(str.trim()) || "unknown".equals(str.trim().toLowerCase())) ? true : false;
    }

    /**
     * 截取字符串，字母、汉字都可以，汉字不会截取半
     *
     * @param str 字符串
     * @param n   截取的长度，字母数，如果为汉字，一个汉字等于两个字母数
     * @return
     */
    public static String subStringByByte(String str, int n) {
        int num = 0;
        try {
            byte[] buf = str.getBytes("GBK");
            if (n >= buf.length) {
                return str;
            }
            boolean bChineseFirstHalf = false;
            for (int i = 0; i < n; i++) {
                if (buf[i] < 0 && !bChineseFirstHalf) {
                    bChineseFirstHalf = true;
                } else {
                    num++;
                    bChineseFirstHalf = false;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str.substring(0, num);
    }

    /**
     * Created by zhoujun on 2014/5/30
     * 验证输入的是否是数字
     *
     * @param num 字符串数字
     * @return
     */
    public static boolean inputIsNum(String num) {
        boolean flag = true;
        try {
            Long.valueOf(num);
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * Created by zhoujun on 2014/5/30
     * 验证字符串为JsonArray字符串
     *
     * @param jsonStr 字符串
     * @return
     */
    public static boolean strIsJsonArrayStr(String jsonStr) {
        boolean flag = true;
        try {
            Object obj = JSON.parseArray(jsonStr);
            if (obj instanceof List) {
            } else {
                flag = false;
            }
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    public static boolean inputIsDouble(String num) {
        boolean flag = true;
        try {
            Double.valueOf(num);
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 判断时间格式 格式必须为“YYYY-MM-dd”
     * 2004-2-30 是无效的
     * 2003-2-29 是无效的
     *
     * @param str
     * @return
     */
    public static boolean isValidDate(String str) {
        //String str = "2007-01-02";
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = (Date) formatter.parse(str);
            return str.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断时间格式 格式必须为“yyyy-MM-dd HH:mm”
     * 2004-2-30 HH:mm 是无效的
     * 2003-2-29 HH:mm 是无效的
     *
     * @param str
     * @return
     */
    public static boolean isValidDate2(String str) {
        //String str = "2007-01-02";
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            Date date = (Date) formatter.parse(str);
            return str.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }








    /**
     * 获取指定后长度的字符串
     *
     * @param str
     * @param lastLength
     * @return
     */
    public static String getStrByLastLength(String str, String lastLength) {
        if (inputIsNum(lastLength)) {
            int number = Integer.valueOf(lastLength);
            if (str.length() > number) {
                return str.substring(str.length() - number);
            } else {
                return str;
            }
        }
        return "";
    }


    /**
     * 判断字符吕是否在对应的字符数组中存在
     *
     * @param s
     * @param strs
     * @return
     */
    public static boolean inArray(String s, String[] strs) {
        boolean flag = false;
        for (String ts : strs) {
            if (s.equals(ts)) {
                flag = true;
                break;
            }
        }
        return flag;
    }



    /**
     * 功能：校验手机号是否符合标准
     *
     * @param mobilePhone
     * @return
     */
    public static boolean isMobilePhone(String mobilePhone) {
        return mobilePhone.matches("^1(((34[0-8]|705)|(3[5-9]|47|5[012789]|78|8[23478])[0-9])|(709|(3[0-2]|45|5[56]|76|8[56])[0-9])|((349|700)|([35]3|77|8[019])[0-9]))\\d{7}$");
    }


    /**
     * 验证是否中国身份证号码
     * @param str
     * @return
     */
    public static boolean isChinaIdCardNo(String str) {

        str = str.toUpperCase();

        //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X。

        if (!str.matches("(^\\d{15}$)|(^\\d{17}([0-9]|X)$)")) {
            //alert('输入的身份证号长度不对，或者号码不符合规定！\n15位号码应全为数字，18位号码末位可以为数字或X。');

            return false;
        }
        //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。

        //下面分别分析出生日期和校验位

        int len, re;

        len = str.length();

        if (len == 15) {

            Date dtmBirth = null;
            boolean bGoodDay = false;

            String reg = "^(\\d{6})(\\d{2})(\\d{2})(\\d{2})(\\d{3})$";
            Matcher m = Pattern.compile(reg).matcher(str);

            if (m.find()) {
                //检查生日日期是否正确
                dtmBirth = new Date("19" + m.group(2) + '/' + m.group(3) + '/' + m.group(4));

                if (dtmBirth.getYear() == Integer.parseInt(m.group(2)) && ((dtmBirth.getMonth() + 1) == Integer.parseInt(m.group(3))) && (dtmBirth.getDate() == Integer.parseInt(m.group(4)))) {
                    bGoodDay = true;
                }
            }

            if (!bGoodDay) {

                //alert('输入的身份证号里出生日期不对！');
                return false;

            } else {

                //将15位身份证转成18位

                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。

                int[] arrInt = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

                String[] arrCh = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

                int nTemp = 0, i;

                str = str.substring(0, 6) + "19" + str.substring(6, str.length());

                for (i = 0; i < 17; i++) {
                    nTemp += Integer.parseInt(str.substring(i, i + 1)) * arrInt[i];

                }
                str += arrCh[nTemp % 11];
                return true;

            }

        } else if (len == 18) {

            Date dtmBirth = null;
            boolean bGoodDay = false;

            String reg = "^(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9]|X)$";
            Matcher m = Pattern.compile(reg).matcher(str);
            if (m.find()) {
                //检查生日日期是否正确
                dtmBirth = new Date(m.group(2) + "/" + m.group(3) + "/" + m.group(4));
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                calendar.setTime(dtmBirth);

                if (calendar.get(Calendar.YEAR) == Integer.parseInt(m.group(2)) && ((calendar.get(Calendar.MONTH) + 1) == Integer.parseInt(m.group(3))) && (calendar.get(Calendar.DATE) == Integer.parseInt(m.group(4)))) {
                    bGoodDay = true;
                }
            }

            if (!bGoodDay) {

                //alert(dtmBirth.getYear());

                //alert(arrSplit[2]);

                //alert('输入的身份证号里出生日期不对！');

                return false;

            } else {

                //检验18位身份证的校验码是否正确。

                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。

                String valnum = null;

                int[] arrInt = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

                String[] arrCh = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

                int nTemp = 0;

                for (int i = 0; i < 17; i++) {

                    nTemp += Integer.parseInt(str.substring(i, i + 1)) * arrInt[i];
                }

                valnum = arrCh[nTemp % 11];

                if (!valnum.equals(str.substring(17, 18))) {
                    //alert('18位身份证的校验码不正确！应该为：' + valnum);
                    return false;
                }
                return true;
            }
        }
        return false;

    }


    /**
     * 功能：校验车架号号是否符合标准
     *
     * @param str
     * @return
     */
    public static boolean isChassisno(String str) {
        boolean flag = true;
        try {
            int len = str.trim().length();
            if (len != 17) {
                flag = false;
            }
        } catch (Exception e) {
            flag = false;
        }
        return flag;
    }




    /**
     * 功能：校验车牌号是否符合标准
     *
     * @param str
     * @return
     */
    public static boolean isCarLicenseno(String str) {
        return str.matches("^[\\u4E00-\\u9FA5]{1}[a-zA-Z]{1}[-]{1}[a-zA-Z0-9]{5}$");
    }
//    public static boolean isMobilePhone(String mobilePhone){
//        String mobilePhoneRegex = SystemConfigFactory.getInstance(CommonSystemConfig.class).getConfigValue( .MOBILE_PHONE_REGEX,ConstantsUtil.MOBILE_PHONE_REGEX_DEFAULT);
//
//        return mobilePhone.matches(mobilePhoneRegex);
//    }



    /**
     * 格式化字符串
     * 如果为空，返回“”
     *
     * @param str
     * @return
     */
    public static String formatString(String str) {
        if (isNullString(str)) {
            return "";
        } else {
            return str;
        }
    }

    /**
     * 替换中间字符串
     *
     * @param str
     * @param n
     * @return
     */
    public static String replaceSubString(String str, int n) {
        String repaceStr = "";
        try {
            //前n位
            String headStr = str.substring(0, n);
            //后n位
            String lastStr = str.substring(str.length() - n, str.length());
            /**
             * 中间的字符串替换*
             */
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < str.length() - 2 * n; i++) {
                sb = sb.append("*");
            }
            repaceStr = headStr + sb.toString() + lastStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return repaceStr;
    }

    /**
     * Author: 沈斌斌
     * Date: 9/3/14 2:39 PM
     * Description: 反转字符数组
     *
     * @param motoArr 原始数组
     * @return String[]
     */
    public static String[] reverseStringArray(String[] motoArr) {
        int length = motoArr.length;

        String[] atarashiArr = new String[length];

        for (int i = 0, j = length - 1; i < length; i++, j--) {
            atarashiArr[i] = motoArr[j];
        }

        return atarashiArr;
    }


    /**
     * 保留2位小数
     *
     * @param amount
     * @return
     */
    public static double numHandle(double amount) {
        //String str = "2007-01-02";
        DecimalFormat fnum = new DecimalFormat("##0.00");
        return Double.parseDouble(fnum.format(amount));
    }




    /**
     * 替换Map对应key值的字符串
     *
     * @param sourceStr 源字符串
     * @param map       需要替换的Map
     * @return
     */
    public static String replaceMapKeyStr(String sourceStr, Map<String, String> map) {
        for (String key : map.keySet()) {
            sourceStr = sourceStr.replaceFirst(key, map.get(key).replaceAll("[+]", "-").replaceAll("/", "_").replaceAll("\n", "").replaceAll("\r", ""));
        }
        return sourceStr;
    }

    /**
     * 替换Map对应key值的字符串
     *
     * @param sourceStr 源字符串
     * @param map       需要替换的Map
     * @return
     */
    public static String[] replaceMapKeyStrArray(String sourceStr, Map<String, String> map) {
        String[] strArray = sourceStr.split(",");
        List<String> targetlist = new ArrayList<>();
        for (String tr : strArray) {
            if (map.containsKey(tr)) {
                // sourceStr = sourceStr.replaceFirst(key, map.get(key).replaceAll("[+]", "-").replaceAll("/", "_").replaceAll("\n", "").replaceAll("\r", ""));
                targetlist.add(map.get(tr));
            }
        }
        return targetlist.toArray(new String[]{});
    }





    /*
     * 返回长度为【strLength】的随机数，在前面补0
     */
    public static String getFixLenthString(int strLength) {

        Random rm = new Random();

        // 获得随机数
        double pross = (1 + rm.nextDouble()) * Math.pow(10, strLength);

        // 将获得的获得随机数转化为字符串
        String fixLenthString = String.valueOf(pross);

        // 返回固定的长度的随机数
        return fixLenthString.substring(0, strLength + 1);
    }


    /**
     * 截取字符串
     *
     * @param str
     * @return
     */
    public static String getShortStr(String str) {
        if (str.length() > 4) {
            return str.substring(0, 4) + "...";
        } else {
            return str;
        }
    }

    /**
     * 截取字符串
     *
     * @param str
     * @return
     */
    public static String idCardStarHandle(String str) {
        if (str.length() == 18) {
            return str.substring(0, 6) + "********" + str.substring(14);
        } else if (str.length() == 15) {
            return str.substring(0, 3) + "********" + str.substring(11);
        }
        return str;
    }

    /**
     * 过滤特殊字符
     *
     * @param str
     * @return
     */
    public static String filterSpecialChar(String str) {
        try {
            String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(str);
            return m.replaceAll("").trim();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("filterSpecialChar error");
        }
        return str;
    }

    /**
     * 截取字符串长度12
     *
     * @param str
     * @return
     */
    public static String getShortStr(String str, int len) {
        if (str.length() > len) {
            return str.substring(0, len);
        } else {
            return str;
        }
    }


    public static String getOutMemonryStr(String str, String flagStr) {
        try {
            DecimalFormat df = new DecimalFormat("#.##");
            String moneyStr = df.format(Double.valueOf(str) / 100);
            return flagStr + moneyStr;
        } catch (Exception e) {
            e.printStackTrace();
            return flagStr + "0.00";
        }
    }

    public static String getOutMemonryStr(long str, String flagStr) {
        try {
            DecimalFormat df = new DecimalFormat("#.##");
            String moneyStr = df.format(Double.valueOf(str) / 100);
            return flagStr + moneyStr;
        } catch (Exception e) {
            e.printStackTrace();
            return flagStr + "0.00";
        }
    }


    /**
     * 获取时间
     * @param str 时间字符串
     * 有效格式:yyyy-MM-dd  yyyy/MM/dd  yyyy-MM-dd HH:mm    yyyy/MM/dd HH:mm    -12222222222~5646464646464
     * @return Date
     */
    public static Date getDateAll(String str) {
        //String str = "2007-01-02";
        DateFormat formatter = null;
        Date date=null;
        if(date==null) {
            try {
                formatter =  new SimpleDateFormat("yyyy-MM-dd");
                date = formatter.parse(str);
            } catch (Exception e) {

            }
        }
        if(date==null) {
            try {
                formatter =  new SimpleDateFormat("yyyy/MM/dd");
                date = formatter.parse(str);
            } catch (Exception e) {

            }
        }
        if(date==null){
            try {
                formatter =  new SimpleDateFormat("yyyy-MM-dd HH:mm");
                date = formatter.parse(str);
            } catch (Exception e) {
            }
        }
        if(date==null){
            try {
                formatter =  new SimpleDateFormat("yyyy/MM/dd HH:mm");
                date = formatter.parse(str);
            } catch (Exception e) {
            }
        }
        if(date==null){
            try {
                formatter =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                date = formatter.parse(str);
            } catch (Exception e) {
            }
        }
        if(date==null){
            try {
                formatter =  new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                date = formatter.parse(str);
            } catch (Exception e) {
            }
        }
        if(date==null){
            if(inputIsNum(str)) {
                try {
                    date = new Date();
                    date.setTime(Long.valueOf(str));
                } catch (Exception e) {
                }
            }
        }
        if(date!=null){
            return date;
        }else{
            return null;
        }
    }

    /**
     * 根据身份证号码获取生日
     *
     * @param IdNO
     * @return
     */
    public static String getIdNOToBirthDay(String IdNO) {
        int leh = IdNO.length();
        int birthYearSpan = 0;
        if (leh == 18) {
            birthYearSpan = 4;
        } else {
            birthYearSpan = 2;
        }
        //年份
        String year = (birthYearSpan == 2 ? "19" : "") + IdNO.substring(6, 6 + birthYearSpan);
        //月份
        String month = IdNO.substring(6 + birthYearSpan, 6 + birthYearSpan + 2);
        //日期
        String day = IdNO.substring(8 + birthYearSpan, 8 + birthYearSpan + 2);
        return year + "-" + month + "-" + day;
    }

    /**
     * 根据身份证号码获取年龄
     *
     * @param IdNO
     * @return
     */
    public static int getIdNOToAge(String IdNO) {
        int leh = IdNO.length();
        int birthYearSpan = 0;
        if (leh == 18) {
            birthYearSpan = 4;
        } else {
            birthYearSpan = 2;
        }
        //年份
        String year = (birthYearSpan == 2 ? "19" : "") + IdNO.substring(6, 6 + birthYearSpan);
        //月份
        String month = IdNO.substring(6 + birthYearSpan, 6 + birthYearSpan + 2);
        //日期
        String day = IdNO.substring(8 + birthYearSpan, 8 + birthYearSpan + 2);
        return getAgeByBirthday(DateUtils.stringToDate(year + "-" + month + "-" + day, "yyyy-MM-dd"));
    }

    /**
     * 根据用户生日计算年龄
     */
    public static int getAgeByBirthday(Date birthday) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        if (cal.before(birthday)) {
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }

        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);

        cal.setTime(birthday);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                // monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                // monthNow>monthBirth
                age--;
            }
        }
        return age;
    }

    /**
     * 根据用户生日计算年龄
     * @param birthday 时间戳
     */
    public static int getAgeByBirthday(long birthday) {
        int age;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(format.format(birthday));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        age = StringUtil.getAgeByBirthday(date);
        return age;
    }

    /**
     * 根据身份证号码获取性别
     *
     * @param IdNO
     * @return
     */
    public static String getIdNOToSex(String IdNO) {
        int leh = IdNO.length();
        int idxSexStart = 0;
        if (leh == 18) {
            idxSexStart = 16;
        } else {
            idxSexStart = 14;
        }
        String idxSexStr = IdNO.substring(idxSexStart, idxSexStart + 1);
        int idxSex = Integer.parseInt(idxSexStr) % 2;
        String sex = idxSex == 1 ? "M" : "F";
        return sex;
    }


    /**
     * 根据身份证号码获取出生天数
     *
     * @param IdNO
     * @return
     */
    public static int getIdNOToAgeDay(String IdNO) {
        int leh = IdNO.length();
        int birthYearSpan = 0;
        if (leh == 18) {
            birthYearSpan = 4;
        } else {
            birthYearSpan = 2;
        }
        //年份
        String year = (birthYearSpan == 2 ? "19" : "") + IdNO.substring(6, 6 + birthYearSpan);
        //月份
        String month = IdNO.substring(6 + birthYearSpan, 6 + birthYearSpan + 2);
        //日期
        String day = IdNO.substring(8 + birthYearSpan, 8 + birthYearSpan + 2);

        Calendar cal = Calendar.getInstance();
        cal.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));
        Calendar calendar = Calendar.getInstance();
        long time1 = cal.getTimeInMillis();
        long time2 = calendar.getTimeInMillis();
        //两个日期相隔的毫秒数
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        //两个日期相隔的天数
        int days = Integer.valueOf(String.valueOf(between_days));
        return days;
    }

    /**
     * 根据生日获取出生天数
     *
     * @param birthDay
     * @return
     */
    public static int getBirthDayToAgeDay(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        cal.setTime(birthDay);
        //cal.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));
        Calendar calendar = Calendar.getInstance();
        long time1 = cal.getTimeInMillis();
        long time2 = calendar.getTimeInMillis();
        //两个日期相隔的毫秒数
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        //两个日期相隔的天数
        int days = Integer.valueOf(String.valueOf(between_days));
        return days;
    }


    public static String captureName(String name) {
        //     name = name.substring(0, 1).toUpperCase() + name.substring(1);
//        return  name;
        char[] cs = name.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);

    }

    /**
     * 校验柬埔寨手机号码格式
     *
     * @param mobile
     * @return
     */
    public static boolean checkCombodiaMobile(String mobile) {
        return Pattern.matches("^[0]?(10|11|12|13|14|15|16|17|18|38|60|61|66|67|68|69|70|77|78|38|60|61|66|67|68|69|70|77|78|80|81|83|84|85|86|87|89|90|92|93|95|98|99)[0-9]{6}$", mobile) ||
                Pattern.matches("^[0]?(31|71|76|88|96|97)[0-9]{7}$", mobile);
    }

}